package com.ruboweb.report;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

import org.apache.log4j.Logger;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.ruboweb.domain.ResultSetData;

/**
 * Clase que genera el Excel
 * 
 */
public class ExcelGenerator {

	private static Logger logger = Logger.getLogger(ExcelGenerator.class);

	/**
	 * Constructor de la clase
	 */
	public ExcelGenerator() {

	}

	/**
	 * Metodo para crear el Excel
	 * 
	 * @param rutaDestino
	 *            Destino del fichero
	 * 
	 * @param perfil
	 *            Perfil del report
	 * 
	 * @param report
	 *            Nombre del report
	 * 
	 */
	public void crearExcel(String rutaDestino, String perfil, String report)
			throws IOException {
		String excelFileName = rutaDestino;
		String sheetName = "Consulta";

		XSSFWorkbook wb = new XSSFWorkbook();
		XSSFSheet sheet = wb.createSheet(sheetName);

		ResultSetData r = new ReportExecutor().ejecutarReport(perfil, report);
		Object[][] datos = r.getDatos();

		XSSFRow row;
		XSSFCell cell;
		for (int i = 0; i < datos.length; i++) {
			row = sheet.createRow(i);

			for (int j = 0; j < datos[0].length; j++) {
				cell = row.createCell(j);

				int cellType = this.obtenerTipoDatoExcel(r.getTipoCelda().get(
						j + 1));
				cell.setCellType(cellType);
				this.rellenarCelda(datos[i][j], cell);

			}
		}

		XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
		FileOutputStream fileOut = new FileOutputStream(excelFileName);

		// write this workbook to an Outputstream.
		wb.write(fileOut);
		fileOut.flush();
		fileOut.close();
	}

	/**
	 * Metodo para obtener el tipo de dato de la celda Excel
	 */
	private int obtenerTipoDatoExcel(int tipoDatoBaseDatos) {
		switch (tipoDatoBaseDatos) {
		case -6:
		case -5:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
			return 0;
		case -4:
		case -3:
		case -2:
		case -1:
		case 0:
		case 1:
		}
		return 1;
	}

	/**
	 * Metodo para establecer el valor con el tipo en la celda Excel
	 */
	private void rellenarCelda(Object o, XSSFCell cell) {
		Double d;
		if (o == null) {
			cell.setCellValue("");
			return;
		}
		if (cell == null) {
			return;
		}
		if (o.getClass().equals(Integer.class)) {
			d = new Double(((Integer) o).intValue());
			cell.setCellValue(d.doubleValue());
			return;
		}
		if (o.getClass().equals(Long.class)) {
			d = new Double(((Long) o).longValue());
			cell.setCellValue(d.doubleValue());
			return;
		}
		if (o.getClass().equals(Float.class)) {
			d = new Double(((Float) o).floatValue());
			cell.setCellValue(d.doubleValue());
			return;
		}
		if (o.getClass().equals(Double.class)) {
			d = new Double(((Double) o).doubleValue());
			cell.setCellValue(d.doubleValue());

			return;
		}
		if (o.getClass().equals(String.class)) {
			cell.setCellValue((String) o);
			return;
		}
		if (o.getClass().equals(Date.class)) {
			cell.setCellValue((Date) o);
			return;
		}

		ExcelGenerator.logger.warn("Se ha encontrado un tipo de dato desconocido para cargar en excel: "
				+ o.getClass());

		String v = o.toString();

		if (v.contains("."))
			;
		try {
			Double val = Double.valueOf(Double.parseDouble(v));
			cell.setCellValue(val.doubleValue());
			return;
		} catch (Exception val) {
			try {
				Integer valaa = Integer.valueOf(Integer.parseInt(v));
				cell.setCellValue(valaa.intValue());
				return;
			} catch (Exception vala) {
				cell.setCellValue(o.toString());
			}
		}
	}
}
